/*
MIT License 

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов, 

https://bmstu.codes/lsx/simodo
*/

#ifndef simodo_ast_Node
#define simodo_ast_Node

/*! \file Node.h
    \brief Структуры абстрактного синтаксического дерева
*/

#include "simodo/ast/OperationCode.h"
#include "simodo/inout/token/Token.h"

#include <string>
#include <vector>


namespace simodo::ast 
{
    /*!
     * \brief Узел абстрактного синтаксического дерева, а также абстрактного дерева операционной семантики.
     *
     * Узел абстрактного синтаксического дерева модифицирован для использования в построении 
     * абстрактного дерева операционной семантики (АДОС, abstract operational semantics tree - AOST). 
     * Однако название оставил стандартное, чтобы подчеркнуть откуда всё происходит. Возможно,
     * когда-нибудь появится время всё переделать на базе интерфейсов (в стиле ООП), а пока пусть будет так.
     * 
     * Каждый узел АДОС является описанием семантического оператора. Смысл этого оператора 
     * раскрывается конкретным интерпретатором.
     */
    class Node {
        // Классы, которые участвуют в формировании Node
        friend class NodeFriend;
        friend class FormationFlow;
        friend class FormationWrapper;

        // Основные атрибуты (должны сохраняться при сериализации)
        std::vector<Node>   _branches;

        std::u16string      _host;      ///< Мнемокод семантики
        OperationCode       _operation; ///< Код операции (уникален внутри владельца семантики)

        inout::Token        _token;     ///< Токен операции (может не совпадать с мнемокодом операции)
        inout::Token        _bound;     ///< Токен границы всех операндов (включая участвующих опосредованно) и операции

    public:
        Node(inout::uri_index_t uri_index=0)
            : _host({})
            , _operation(0)
            , _token( { inout::LexemeType::Empty, {}, {uri_index, {0,0,0,0}} } )
            , _bound( { inout::LexemeType::Empty, {}, {uri_index, {0,0,0,0}} } )
        {}

        Node(std::u16string host, OperationCode op, inout::Token symbol, inout::Token bound)
            : _host(host)
            , _operation(op)
            , _token(symbol)
            , _bound(bound)
        {}

    public:
        const std::vector<Node> &   branches()  const   { return _branches; }
        OperationCode               operation() const   { return _operation; }
        const inout::Token &        token()     const   { return _token; }
        const inout::Token &        bound()     const   { return _bound; }
        const std::u16string &      host()      const   { return _host; }

    public:
        void swap(Node & node);
    };

}

#endif // simodo_ast_Node
